/************************************************************************/
/* Resources                                                            */
/************************************************************************/
#include "Resources/Tiles/Tilemap.h"

namespace TD_Resources {
	/************************************************************************/
	/* Protected functions                                                  */
	/************************************************************************/
	
	bool Tilemap::borderlineTop(unsigned int i, unsigned int j) {
		if(i == 0) {
			return true;
		}

		return false;
	}

	bool Tilemap::borderlineBottom(unsigned int i, unsigned j) {
		if(i == m_numTiles.y - 1) {
			return true;
		}
		return false;
	}

	bool Tilemap::borderlineLeft(unsigned int i, unsigned int j) {
		if(j == 0) {
			return true;
		}
		return false;
	}

	bool Tilemap::borderlineRight(unsigned int i, unsigned int j) {
		if(j == m_numTiles.x - 1) {
			return true;
		}
		return false;
	}



	bool Tilemap::loadTileMatrix(const string &tileMatrixStr) {
		/************************************************************************/
		/* IMPLEMENTAR NO RESOURCE MANAGER                                    */
		/************************************************************************/
		string newPath = TD_Game::resourcesRoot + tileMatrixStr;
		ifstream tileMap(newPath.c_str());

		
		if(tileMap == NULL) {
			return false;
		}

		m_pTilemapMatrix = new Matrix2D(m_numTiles);

		for(int i = 0; i < m_numTiles.y; i++) {
			for(int j = 0; j < m_numTiles.x; j++) {
				int valueFromFile;
				tileMap >> valueFromFile;
				(*m_pTilemapMatrix)(i, j) = valueFromFile;

				if(tileMap.fail() == true) {
					tileMap.close();
					return false;
				}

			}
		}
		tileMap.close();
		return true;
	}


	Tile * Tilemap::createNewTile(unsigned int i, unsigned int j, unsigned int x, unsigned int y, int relativePosition) {
		Tile *nuTile = new Tile();
		*nuTile = *m_pTileset->getTile(relativePosition);
		Coord2D nuTilePos;
		nuTilePos.x = m_position.x + m_tileSize.x*3*j + m_tileSize.x*x;
		nuTilePos.y = m_position.y + m_tileSize.y*3*i + m_tileSize.y*y;
		nuTile->setPosition(nuTilePos);
		return nuTile;
	}
	/************************************************************************/
	/* Constructors                                                         */
	/************************************************************************/
	Tilemap::Tilemap() {
		m_pTileset = NULL;
	}

	Tilemap::Tilemap(const Tilemap &rhs) : BaseEntity(rhs) {
		m_pTileset = rhs.getTileset();
		m_numTiles = rhs.getNumberOfTiles();
		m_tileSize = rhs.getTilesize();
	}


	Tilemap & Tilemap::operator=(const Tilemap &rhs) {
		m_pTileset = rhs.getTileset();
		m_numTiles = rhs.getNumberOfTiles();
		m_tileSize = rhs.getTilesize();
		return(*this);
	}

	Tilemap::Tilemap(const Tileset *g_pTileset) {
		m_pTileset = g_pTileset;
	}

	Tilemap::~Tilemap() {

	}

	/************************************************************************/
	/* Functionalities                                                      */
	/************************************************************************/
	bool Tilemap::loadTilemap(const string &tileMapStr, const Coord2D & mapPosition, const Coord2D &tileSize, const Coord2D &numTiles) {
		
		m_numTiles = numTiles;
		m_tileSize = tileSize;
		m_position = mapPosition;

		ifstream tileMap(tileMapStr.c_str());
		if(tileMap == NULL) {
			return false;
		}

		//Alocate space for the tileset matrix:
		unsigned int totalTiles = m_numTiles.x * m_numTiles.y;

		for(int i = 0; i < m_numTiles.y; i++) {
			for(int j = 0; j < m_numTiles.x; j++) {
				TileType tileType = invalidTile;
				int valueFromFile;
				tileMap >> valueFromFile;

				tileType = static_cast<TileType>(valueFromFile);

				if(tileMap.fail() == true) {
					tileMap.close();
					return false;
				}

				if(tileType != invalidTile) {
					Tile *nuTile = new Tile(); 
					*nuTile = *m_pTileset->getTile(tileType);
					Coord2D nuTilePos;
					nuTilePos.x = m_position.x + m_tileSize.x*j;
					nuTilePos.y = m_position.y + m_tileSize.y*i;
					nuTile->setPosition(nuTilePos);
					m_tileVector.push_back(nuTile);
				} else {
					tileMap.close();
					return false;
				}
			}
		}
		return true;
	}

	void Tilemap::render(SDL_Surface *const g_destSurface, unsigned int deltaTime) {

		for(unsigned int i = 0; i < m_tileVector.size(); i++) {
			m_tileVector[i]->render(g_destSurface, deltaTime);
		}
	}

	
}